package com.zd.commodity.productMng.biz.impl;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import utils.Util;

import com.zd.commodity.biz.impl.BaseBiz;
import com.zd.commodity.brandMng.dao.IBrandShowDao;
import com.zd.commodity.brandMng.entity.BrandShow;
import com.zd.commodity.categoryMng.dao.ICategoryDao;
import com.zd.commodity.categoryMng.entity.Category;
import com.zd.commodity.productMng.biz.IProductBiz;
import com.zd.commodity.productMng.dao.IAttrRuleDao;
import com.zd.commodity.productMng.dao.INameProductRuleDao;
import com.zd.commodity.productMng.dao.IProductAttrDao;
import com.zd.commodity.productMng.dao.IProductAttrDictDao;
import com.zd.commodity.productMng.dao.IProductAttrGroupDao;
import com.zd.commodity.productMng.dao.IProductAttrValueDao;
import com.zd.commodity.productMng.dao.IProductDao;
import com.zd.commodity.productMng.dao.IProductPriceDao;
import com.zd.commodity.productMng.entity.AttrCheck;
import com.zd.commodity.productMng.entity.NameProductRule;
import com.zd.commodity.productMng.entity.Product;
import com.zd.commodity.productMng.entity.ProductAttr;
import com.zd.commodity.productMng.entity.ProductAttrDict;
import com.zd.commodity.productMng.entity.ProductAttrValue;
import com.zd.commodity.productMng.entity.ProductCheck;
import com.zd.commodity.productMng.entity.ProductIntroduction;
import com.zd.commodity.productMng.entity.ProductPrice;
import com.zd.commodity.productMng.entity.ProductSeries;
import com.zd.commodity.product_pic.dao.IProductPicDao;
import com.zd.commodity.product_pic.entity.ProductPic;
import com.zd.commodity.userMng.entity.User;

@Service("productBiz")
public class ProductBizImpl extends BaseBiz<Product> implements IProductBiz {

	private IProductDao productDao;
	@Autowired
	private IProductAttrDao productAttrDao;
	@Autowired
	private IProductAttrDictDao productAttrDictDao;
	@Autowired
	private IAttrRuleDao attrRuleDao;
	@Autowired
	private ICategoryDao categoryDao;
	@Autowired
	private IBrandShowDao brandShowDao;
	@Autowired
	private IProductAttrValueDao productAttrValueDao;
	@Autowired
	private INameProductRuleDao nameProductRuleDao;
	@Autowired
	private IProductAttrGroupDao productAttrGroupDao;
	
	
	@Override
	public Object[] excelProductAttrCheck() {
		/*
		 *  1.先数据字典检查，如果excel中的关键属性不全则校验失败，在此商品校验结果处写上"关键属性不全"
		 *	a.再看关键属性是否有数据字典，如果有数据字典则检查其字典中是否包括excel的参数值的原始值，如果没有，则在此行写入"数据字典缺失此值！"
		 *	2.查询属性规则表进行文本正则检查，属性规则表中包含的属性不能为空，且需符合规则
		 */
		List<String[]> excelData = readExecl(new HashMap<Integer, String>());
		StringBuilder result = new StringBuilder();//校验结果
		boolean success=true;//校验是否通过
		//Map<String(商品名称),ProductCheck>
		//将excel数据封装成Map<String(商品名称),ProductCheck>形式
		Map<String,ProductCheck> productMap = new HashMap();
		for(int i=0;i<excelData.size();i++){
			ProductCheck productCheck = null;
			Map<Long,AttrCheck> attrMap;
			
			if(productMap.get(excelData.get(i)[0])==null){//没有此商品
				productCheck = new ProductCheck(null, excelData.get(i)[0], 
						excelData.get(i)[3], null, excelData.get(i)[2], null, 
						excelData.get(i)[4], null,i,excelData.get(i)[1]);
				Category categoryT1 = new Category();
				categoryT1.setName(productCheck.getCategoryName());
				productCheck.setCategoryId(categoryDao.getList(categoryT1, null, null).get(0).getId());
				attrMap = new HashMap<Long, AttrCheck>();
				
			}else{//已包括此商品
				productCheck = productMap.get(excelData.get(i)[0]);
				attrMap = productMap.get(excelData.get(i)[0]).getAttrs();
				if(attrMap == null){//有商品，但是没有属性（第一条属性数据库不存在的情况）
					attrMap = new HashMap<Long, AttrCheck>();
				}
			}
			//根据分类名，属性组名，属性名唯一确定属性id
			Map<String,String> namesParam = new HashMap();
			namesParam.put("categoryName", excelData.get(i)[3]);
			namesParam.put("attrGroupName", excelData.get(i)[4]);
			namesParam.put("attrName", excelData.get(i)[5]);
			List attrList = productAttrDao.getListBySql("findUniqueAttr", namesParam);
			String queryAttrResult;
			if(attrList.size()==0){//再去查询属性映射
				namesParam.put("supplierName", excelData.get(i)[7]);
				attrList = productAttrDao.getListBySql("findUniqueAttrByMapping", namesParam);
			}
			if(attrList.size()>0){//根据分类名，属性组，属性名能查找到属性id
				Object[] object = (Object[]) attrList.get(0);
				AttrCheck attrCheck = new AttrCheck(Long.valueOf(object[0].toString()), 
						object[3].toString(), excelData.get(i)[6], 
						Integer.valueOf(object[1].toString()), 
						Integer.valueOf(object[2].toString()), i);
				attrMap.put(attrCheck.getId(), attrCheck);
				productCheck.setAttrs(attrMap);
				productMap.put(excelData.get(i)[0], productCheck);
			}else{
				success=false;
				excelData.get(i)[8]+="请先建立此属性或添加属性映射！";
			}
			
		}
		for(Entry<String, ProductCheck> product : productMap.entrySet()){
			//根据分类id查询此分类的关键属性，检查关键属性是否齐全
			ProductAttr keyAttrT1 = new ProductAttr();
			keyAttrT1.setIsKeyAttr("1");
			Category category = new Category();
			category.setId(product.getValue().getCategoryId());
			keyAttrT1.setCategory(category);
			List<ProductAttr> keyAttrList = productAttrDao.getList(keyAttrT1, null, null);
			
			for (ProductAttr keyAttr : keyAttrList) {
				if(product.getValue().getAttrs().get(keyAttr.getId())==null){
					result.append(productAttrGroupDao.get(keyAttr.getGroupId()).getName() +
							">"+keyAttr.getName()+",");
				}
			}
			if(result.length()>0){
				result.deleteCharAt(result.length()-1);
				result.append("关键属性缺失！");
				success=false;
				excelData.get(product.getValue().getFirstRowNum())[8]+=result;
			}
			
			//校验此商品型号
			Map<String,String> modelArgMap = new HashMap();
			modelArgMap.put("categoryId", String.valueOf(product.getValue().getCategoryId()));
			modelArgMap.put("brandName", product.getValue().getBrandName());
			modelArgMap.put("attrId", "-1");
			List<Object[]> modelRegexList = attrRuleDao.getListBySql("getRegexByCategoryAndBrand", modelArgMap);
			if(modelRegexList.size()>0){//属性规则表有记录
				if(product.getValue().getModel()==null&&"".equals(product.getValue().getModel())){
					 excelData.get(product.getValue().getFirstRowNum())[8]+="此商品型号有规则，不能为空："+modelRegexList.get(0)[1].toString()+"!";
					 success=false;
				}
				Pattern pattern = Pattern.compile(modelRegexList.get(0)[0].toString());
				Matcher matcher = pattern.matcher(product.getValue().getModel());
				if(!matcher.matches()){//如果正则校验失败
					excelData.get(product.getValue().getFirstRowNum())[8]+="此型号值不符合规则："+modelRegexList.get(0)[1].toString()+"!";
					success=false;
				}
			}
			
			//遍历此商品的属性
			for(Entry<Long, AttrCheck> attr : product.getValue().getAttrs().entrySet()){
				
				if(attr.getValue().getHasDict()==1){//如果此属性有数据字典，则检查数据字典是否存在其属性值
					ProductAttr attrT1 = new ProductAttr();
					attrT1.setId(attr.getKey());
					ProductAttrDict dictT1 = new ProductAttrDict();
					dictT1.setProductAttr(attrT1);
					dictT1.setOriginalValue(attr.getValue().getValue());
					List<ProductAttrDict> list = productAttrDictDao.getList(dictT1, null, null);
					if(list.size()==0){//数据字典缺失此属性值
						excelData.get(attr.getValue().getRowNum())[8]+="请在数据字典中补充此属性值！";
						success=false;
					}
				}else{//没有数据字典的属性，根据分类，品牌查询属性规则表，表中有的属性进行正则匹配
					Map<String,String> argMap = new HashMap();
					argMap.put("categoryId", String.valueOf(product.getValue().getCategoryId()));
					argMap.put("brandName", product.getValue().getBrandName());
					argMap.put("attrId", String.valueOf(attr.getKey()));
					List<Object[]> regexList = attrRuleDao.getListBySql("getRegexByCategoryAndBrand", argMap);
					if(regexList.size()>0){//属性规则表有记录
						if(attr.getValue().getValue()==null&&"".equals(attr.getValue().getValue())){
							 excelData.get(attr.getValue().getRowNum())[8]+="此属性值有规则，不能为空："+regexList.get(0)[1].toString()+"!";
							 success=false;
						}
						Pattern pattern = Pattern.compile(regexList.get(0)[0].toString());
						Matcher matcher = pattern.matcher(attr.getValue().getValue());
						if(!matcher.matches()){//如果正则校验失败
							excelData.get(attr.getValue().getRowNum())[8]+="此属性值不符合规则："+regexList.get(0)[1].toString()+"!";
							success=false;
						}
					}
				}
			}
		}
		XSSFWorkbook wb = new XSSFWorkbook();
		if(success==false){//校验失败则生成供修改的excel
			XSSFSheet sheet = wb.createSheet("sheet1");
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			//写入标题
			try {
				sheet = Util.writeExcel(sheet, new String[]{"商品名称","型号","品牌名称","分类名称","属性组名称","属性名称","属性值","供应商名称","校验结果"});
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for(String[] row:excelData){
				try {
					sheet = Util.writeExcel(sheet, row);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}/*else{//如果校验通过，则顺便将数据保存到数据库
			saveProductAfterCheck(productMap);
		}*/
		return new Object[]{success,wb,productMap};
	}
	

	public void saveProductAfterCheck(Map<String, ProductCheck> productMap) {
		Set<Entry<String, ProductCheck>> entrySet = productMap.entrySet();
		for (Entry<String, ProductCheck> productEntry : entrySet) {
			ProductCheck productCheck = productEntry.getValue();
			
			//保存商品
			Product product = new Product();
			BrandShow brandShowT1 = new BrandShow();
			brandShowT1.setName(productCheck.getBrandName());
			Category category = new Category();
			category.setId(productCheck.getCategoryId());
			User user = (User) ServletActionContext.getRequest().getSession().getAttribute("user");
			Timestamp timestamp = new Timestamp(System.currentTimeMillis());
			String uuid = java.util.UUID.randomUUID().toString();
			String productNo = (uuid.substring(0, 8) + uuid.substring(9, 13)).toUpperCase();
			
			product.setBrandShow(brandShowDao.getList(brandShowT1, null, null).get(0));
			product.setModel(productCheck.getModel());
			product.setCategory(category);
			product.setName(productCheck.getName());
			product.setCreator(user.getUsername());
			product.setCreationTime(timestamp);
			product.setUpdater(user.getUsername());
			product.setUpdateTime(timestamp);
			product.setSku(productNo);
			product.setIsNamed(0);
			product.setStatus(0);
			productDao.add(product);
			
			//保存属性值
			Set<Entry<Long, AttrCheck>> attrsSet = productCheck.getAttrs().entrySet();
			for (Entry<Long, AttrCheck> attr : attrsSet) {
				ProductAttr productAttr = new ProductAttr();
				productAttr.setId(attr.getKey());
				
				ProductAttrValue productAttrValue = new ProductAttrValue();
				productAttrValue.setProduct(product);
				productAttrValue.setProductAttr(productAttr);
				if(attr.getValue().getHasDict()==1){//如果此属性有数据字典，则保存标准值
					ProductAttrDict dictT1 = new ProductAttrDict();
					dictT1.setProductAttr(productAttr);
					dictT1.setOriginalValue(attr.getValue().getValue());
					productAttrValue.setValue(productAttrDictDao.getList(dictT1, null, null).get(0).getStandardValue());
				}else{//如果此属性没有数据字典，则保存本来的值
					productAttrValue.setValue(attr.getValue().getValue());
				}
				productAttrValueDao.add(productAttrValue);
			}
		}
	}

	public int[] updateNameProductByRule(){
		Product productT1 = new Product();
		productT1.setIsNamed(0);
		//查询出所有未标准命名的商品
		List<Product> productList = productDao.getList(productT1, null, null);
		int[] result = new int[2];
		result[0]=productList.size();
		int successCount=0;
		for (Product product : productList) {
			//查询商品属性值
			ProductAttrValue attrValueT1 = new ProductAttrValue(); 
			attrValueT1.setProduct(product);
			List<ProductAttrValue> attrList = productAttrValueDao.getList(attrValueT1, null, null);
			Map<Long,ProductAttrValue> attrValueMap = new HashMap<>();
			for (ProductAttrValue productAttrValue : attrList) {
				attrValueMap.put(productAttrValue.getProductAttr().getId(), productAttrValue);
			}
			//根据分类，品牌查询规则
			NameProductRule ruleT1 = new NameProductRule();
			ruleT1.setCategory(product.getCategory());
			ruleT1.setBrandShow(product.getBrandShow());
			List<NameProductRule> ruleQueryList = nameProductRuleDao.getList(ruleT1, null, null);
			//遍历规则，检查规则有没有属性值要求
			NameProductRule rule = null;
			for (NameProductRule nameProductRule : ruleQueryList) {
				if(nameProductRule.getProductAttr()!=null){//如果有属性值要求则检查此商品是否符合
					if(attrValueMap.get(nameProductRule.getProductAttr().getId())!=null
							&&attrValueMap.get(nameProductRule.getProductAttr().getId()).getValue().equals(nameProductRule.getAttrStandardValue())){
						rule = nameProductRule;
						break;
					}
				}else{
					rule = nameProductRule;
				}
			}
			
			//生成商品名称
			String[] attrIds = rule.getPartakeNameAttr().split(",");
			String[] types = rule.getType().split(",");
			Map<String,String> partakeAttrValueMap = new HashMap();
			for (int i=0;i<attrIds.length;i++) {
				//type:1使用标准值，2使用简称
				String attrValue;
				if(attrIds[i].equals("-1")){
					attrValue = product.getModel();
				}else{
					if(types[i].equals("1")){
						attrValue = attrValueMap.get(Long.valueOf(attrIds[i])).getValue();
					}else{
						ProductAttrDict productAttrDictT1 = new ProductAttrDict();
						ProductAttr productAttr = new ProductAttr();
						productAttr.setId(Long.valueOf(attrIds[i]));
						productAttrDictT1.setProductAttr(productAttr);
						attrValue = productAttrDictDao.getList(productAttrDictT1, null, null).get(0).getShortValue();
					}
				}
				partakeAttrValueMap.put(attrIds[i], attrValue);
			}
			String name = Util.replacWithMap(rule.getTemplate(), "{:", ":}", partakeAttrValueMap);
			//查询生成的商品名称是否已存在
			Product productNameQueryT1 = new Product();
			productNameQueryT1.setName(name);
			List<Product> productNameQueryList = productDao.getList(productNameQueryT1, null, null);
			if(productNameQueryList.size()>0){
				productDao.delete(product.getId());
				Map<String,String> argMap = new HashMap<>();
				argMap.put("productId", String.valueOf(product.getId()));
				productAttrValueDao.executeSql("deleteAttrValueByProduct", argMap);
				continue;
			}
			product.setName(name);
			product.setIsNamed(1);
			productDao.update(product);
			successCount++;
		}
		result[1]=successCount;
		return result;
	}

	public IProductDao getProductDao() {
		return productDao;
	}

	@Autowired
	public void setProductDao(IProductDao productDao) {
		this.productDao = productDao;
	    this.setBaseDao(productDao);
	}
	
	@Autowired
	private IProductPicDao productPicDao;
	@Autowired
	private IProductPriceDao productPriceDao;
	
	/**
	 *  添加商品的基本详情信息
	 */
	public void addProduct(Product product, long[] picIds){
		if(picIds!=null && !picIds.equals("")){
			for (long picId : picIds) {
				ProductPic productPic = productPicDao.get(picId);
				if(productPic!=null){
					product.getProductPicList().add(productPic);
				}
			}
		}
		productDao.add(product);
	}
	
	/**
	 *  修改商品的基本详情信息
	 */
	public void updateProduct(Product product, long[] picIds){
		//先删除所有图片
		product.setProductPicList(new HashSet<ProductPic>());
		if(picIds!=null && !picIds.equals("")){
			for (long picId : picIds) {
				ProductPic productPic = productPicDao.get(picId);
				if(productPic!=null){
					product.getProductPicList().add(productPic);
				}
			}
		}
		productDao.update(product);
	}

	@Override
	public void saveExcelSave(List<String[]> data) {
		for (String[] strings : data) {
			//保存商品
			Product product = new Product();
			product.setName(strings[0]);
			product.setStatus(1);
			BrandShow brandShow = new BrandShow();
			brandShow.setId(Long.valueOf(strings[1]));
			product.setBrandShow(brandShow);
			Category category = new Category();
			category.setId(Long.valueOf(strings[2]));
			product.setCategory(category);
			//保存系列图片
			Set s =new HashSet();
			String series = strings[3];
			String[] split = series.split("\\|");
			Long Introduction = null ;
			Long seriesId = null ;
			for (String string : split) {
				String[] split2 = string.split("-");
				ProductPic productPic = new ProductPic();
				ProductPic productPic2 = productPicDao.get(Long.valueOf(split2[2]));
				Introduction = Long.valueOf(split2[1]);
				seriesId = Long.valueOf(split2[0]);
				s.add(productPic2);
			}
			product.setProductPicList(s);
			//详情
			ProductIntroduction productIntroduction = new ProductIntroduction();
			productIntroduction.setId(Introduction);
			product.setProductIntroduction(productIntroduction);
			//系列
			ProductSeries productSeries = new ProductSeries();
			productSeries.setId(seriesId);
			product.setProductSeries(productSeries);
			productDao.add(product);
			//保存价格
			for (int i =4 ; i < 7; i++) {
				ProductPrice productPrice = new ProductPrice();
				productPrice.setPrice(Double.valueOf(strings[i]));
				productPrice.setProduct(product);
				productPrice.setType(i-3);
				productPriceDao.add(productPrice);
			}
		}
		
	}

}
